/* eslint-disable default-case */
/* eslint-disable no-restricted-syntax */
/* eslint-disable guard-for-in */
/* eslint-disable prefer-destructuring */
/* eslint-disable class-methods-use-this */
/* eslint-disable max-classes-per-file */
import Konva from 'konva'
import { IKonvaCommon } from '@/components/konvaUnits/common/IKonvaCommon'
import KonvaUtils from '@/components/konvaUnits/utils/konvaUtils'
import { Pillar } from '@/components/konvaUnits/common/pillar'
import { useStore } from '@/store/index'
import { FenceClass } from '@/store/fence'

const drawFenceText = (id: string, length: number, text: string, dash: boolean) => {
  const group = new Konva.Group({ id: `${id}-fenceText` })
  const offset: number = 20
  const arrowOffset: number = 20 / 2
  const arrowSize: number = 5

  if (dash) {
    const fenceDash = new Konva.Line({
      id: `${id}-fenceText`,
      points: [0, 0, length, 0],
      dash: [10, 10],
      stroke: 'grey',
      strokeWidth: 2
    })
    group.add(fenceDash)
  } else {
    const lines = new Konva.Shape({
      id: `${id}-fenceText`,
      sceneFunc(ctx) {
        ctx.fillStyle = 'grey'
        ctx.lineWidth = 0.5
        ctx.moveTo(0, 0)
        ctx.lineTo(0, offset)
        ctx.moveTo(length, 0)
        ctx.lineTo(length, offset)
        ctx.stroke()
      }
    })
    const bottomArrow = new Konva.Shape({
      id: `${id}-fenceText`,
      sceneFunc(ctx, shape) {
        // top pointer
        ctx.translate(0, arrowOffset)
        ctx.moveTo(arrowSize, -arrowSize)
        ctx.lineTo(0, 0)
        ctx.lineTo(arrowSize, arrowSize)
        // line
        ctx.moveTo(0, 0)
        ctx.lineTo(length, 0)
        ctx.lineTo(length, 0)
        // bottom pointer
        ctx.moveTo(length - arrowSize, -arrowSize)
        ctx.lineTo(length, 0)
        ctx.lineTo(length - arrowSize, arrowSize)
        ctx.strokeShape(shape)
      },
      stroke: 'grey',
      strokeWidth: 0.5
    })
    group.add(bottomArrow, lines)
  }

  const bottomText = new Konva.Text({
    id: `${id}-fenceText`,
    x: length / 2 - 10,
    y: dash ? arrowOffset : arrowOffset - 15,
    text: `${dash ? text : parseInt(text, 10) / 1000}${dash ? '' : 'm'}`,
    padding: 2,
    fill: 'black'
  })
  group.add(bottomText)
  // group.zIndex(2)
  return group
}

const drawFence = (id: string, start: number[], length: number, angle: number, text: string) => {
  const group = new Konva.Group({ id })
  const fenceText = drawFenceText(id, length, text, true)
  const fence = new Konva.Line({
    points: [0, 3, length, 3],
    stroke: 'grey'
  })
  group.add(fenceText, fence)
  group.x(start[0])
  group.y(start[1])
  group.rotation(angle)
  return group
}

const fixPillarPos = (x: number, y: number, width: number, height: number, rotation: number) => {
  const points = KonvaUtils.getAnglePoints([x, y], rotation, width)
  return [points[2], points[3]]
}

export const drawFenceGroup = (
  id: string,
  start: number[],
  length: number,
  angle: number,
  scale: number,
  beginPillar: { id: ''; x: 0; y: 0; rotation: 0; width: 0; height: 0 },
  endPillar: { id: ''; x: 0; y: 0; rotation: 0; width: 0; height: 0 },
  addStore: boolean
) => {
  const group = new Konva.Group({ id })
  const store = useStore()
  let startPos = start
  let beginPos = start
  let end = { id: '', x: 0, y: 0, rotation: 0, width: 0, height: 0 }
  let totalLength = 0
  const fenceList = KonvaUtils.splitFences(
    length +
      (beginPillar ? -store.pillar.diameter[0] : 0) +
      (endPillar ? store.pillar.diameter[0] : 0),
    store.globalParam.lineType
  )
  if (fenceList.length < 1) return { fence: null, points: [] }
  if (beginPillar.id === '') {
    const pillar = new Pillar()
    const drawPillar = pillar.draw(id, [startPos[0], startPos[1]], angle, addStore)
    group.add(pillar.pillar)
    totalLength += store.pillar.diameter[0]
    startPos = fixPillarPos(
      drawPillar.x,
      drawPillar.y,
      drawPillar.width,
      drawPillar.height / 2,
      drawPillar.rotation
    )
    beginPillar = drawPillar
  } else {
    startPos = fixPillarPos(
      beginPillar.x,
      beginPillar.y,
      beginPillar.width,
      beginPillar.height,
      beginPillar.rotation
    )
    startPos = KonvaUtils.fixStartPos(
      startPos,
      beginPillar.rotation,
      [beginPillar.width, beginPillar.height / 2],
      angle
    )
    beginPos = startPos
  }

  for (const i in fenceList) {
    const fence = drawFence(
      `${id}-${store.drawing.fences.size + 1}`,
      startPos,
      fenceList[i] / scale,
      angle,
      fenceList[i].toString()
    )
    group.add(fence)
    if (addStore) {
      store.drawingAction.setFence(
        `${id}-${store.drawing.fences.size + 1}`,
        new FenceClass(
          startPos,
          angle,
          store.fence.height,
          fenceList[i],
          store.fence.color,
          store.fence.spacing,
          store.fence.silk
        )
      )
    }
    totalLength += fenceList[i] + 10
    const points = KonvaUtils.fixRadian(startPos, angle, fenceList[i] / scale)
    startPos = [points.points[2], points.points[3]]
    if (parseInt(i, 10) === fenceList.length - 1 && endPillar.id !== '') {
      break
    }
    const pillar = new Pillar()
    end = pillar.draw(id, [points.points[2], points.points[3]], angle, addStore)
    group.add(pillar.pillar)
    totalLength += store.pillar.diameter[0]
    startPos = fixPillarPos(end.x, end.y, end.width, end.height, angle)

    // startPos = KonvaUtils.fixStartPos(
    //   [drawPillar.x, drawPillar.y],
    //   drawPillar.rotation,
    //   [drawPillar.width, drawPillar.height],
    //   angle
    // )
  }

  const lineLength = KonvaUtils.getPositionLength(beginPos, startPos)
  let groupTextPoints = KonvaUtils.fixRadian(beginPos, angle - 90, 20).points
  const groupText = drawFenceText(id, lineLength, totalLength.toString(), false)
  groupText.x(groupTextPoints[2])
  groupText.y(groupTextPoints[3])
  groupText.rotation(angle)
  groupText.id(`${id}-text`)
  group.add(groupText)
  groupTextPoints = KonvaUtils.fixRadian(beginPos, angle, 10).points
  const rectSelect = new Konva.Rect({
    id: `${id}-rect-select`,
    x: groupTextPoints[2],
    y: groupTextPoints[3],
    rotation: angle,
    width: lineLength - 20,
    strokeEnabled: false,
    stroke: 'red',
    height: 10
  })
  group.add(rectSelect)
  rectSelect.moveToBottom()
  return {
    fence: group,
    points: start.concat(startPos),
    beginPillar,
    endPillar: end
  }
}

export class Fence implements IKonvaCommon {
  points!: number[]

  height: number = 2000

  width: number = 1400

  color: string = 'black'

  spacing: number[] = [20, 100]

  silk: number = 3

  konvaGroup: Konva.Group

  constructor() {
    this.konvaGroup = new Konva.Group()
    this.konvaGroup.on('mouseover', (e) => {
      this.mouseover(e)
    })
    this.konvaGroup.on('mouseout', (e) => {
      this.mouseout(e)
    })
  }

  draw(
    points: number[],
    width: number[],
    angle: number,
    scale: number,
    beginPillar: boolean,
    endPillar: boolean
  ): void {
    this.points = points
    this.width = width[0]
    if (width[0] < 200) return
    this.konvaGroup = drawFenceGroup(
      '',
      [points[0], points[1]],
      width[0],
      angle,
      scale,
      beginPillar,
      endPillar,
      true
    ).fence
  }

  mouseover(e: any): void {
    console.log('mouseover', e)
  }

  mouseout(e: any): void {
    console.log('mouseout', e)
  }

  clickOn(e: any): void {}

  dbClickOn(e: any): void {
    console.log('dbClickOn', e)
  }

  remove(e: any): void {}
}

export class Fences implements IKonvaCommon {
  points!: number[]

  height: number = 2000

  width: number = 1400

  color: string = 'black'

  spacing: number[] = [20, 100]

  silk: number = 3

  konvaGroup!: Konva.Group

  constructor() {
    this.konvaGroup = new Konva.Group()
    this.konvaGroup.on('mouseover', (e) => {
      this.mouseover(e)
    })
    this.konvaGroup.on('mouseout', (e) => {
      this.mouseout(e)
    })
  }

  draw(points: number[], width: number[], angle: number, scale: number): void {
    this.points = points
    const addStore = true
    if (width[0] < 200 || width[1] < 200) return
    let fences = drawFenceGroup(
      '',
      [points[0], points[1]],
      width[0],
      0,
      scale,
      true,
      true,
      addStore
    )
    this.konvaGroup.add(fences.fence)
    fences = drawFenceGroup(
      '',
      [fences.points[2], fences.points[3]],
      width[1],
      90,
      scale,
      false,
      false,
      addStore
    )
    this.konvaGroup.add(fences.fence)
    fences = drawFenceGroup(
      '',
      [points[0], fences.points[3]],
      width[0],
      0,
      scale,
      true,
      true,
      addStore
    )
    this.konvaGroup.add(fences.fence)
    fences = drawFenceGroup(
      '',
      [fences.points[0], fences.points[1]],
      width[1],
      -90,
      scale,
      false,
      false,
      addStore
    )
    this.konvaGroup.add(fences.fence)
  }

  mouseover(e: any): void {
    console.log('mouseover', e)
  }

  mouseout(e: any): void {
    console.log('mouseout', e)
  }

  clickOn(e: any): void {}

  dbClickOn(e: any): void {
    console.log('dbClickOn', e)
  }

  remove(e: any): void {}
}
